package org.lora.webframework.scheduler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.lora.core.annotation.Action;
import org.lora.core.annotation.AutoAssemble;
import org.lora.core.context.WebContext;
import org.lora.core.mybatis.OrderByBean;
import org.lora.core.mybatis.Page;
import org.lora.mvc.annotation.RequestPath;
import org.lora.mvc.annotation.ResponseJSON;
import org.lora.mvc.entity.ViewData;
import org.lora.quartz.IQuartzService;
import org.lora.quartz.entity.SchedulerInfo;
import org.lora.util.DateUtil;
import org.lora.util.StringUtil;
import org.lora.webframework.common.CommonConstant;
import org.lora.webframework.common.JsonResult;
import org.lora.webframework.common.WebframeBaseAction;
import org.lora.webframework.scheduler.entity.QrtzJobDetail;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.impl.triggers.SimpleTriggerImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * <p>
 * 类名:QuartzMaintanceAction
 * </p>
 * 描述:<br>
 * 创建时间:2016年11月8日 下午4:11:07<br>
 * 
 * @author Bladnir@outlook.com<br>
 *         修改历史:<br>
 *         2016年11月8日 Bladnir 创建<br>
 */
@Action
@RequestPath(path = "/webframework/scheduler")
public class SchedulerAction extends WebframeBaseAction {

	@AutoAssemble
	private ISchedulerService schedulerService;

	/**
	 * 打开quartz总体预览信息页面
	 * 
	 * @return
	 */
	@RequestPath(path = "/showOverview")
	public ViewData showOverview() {
		return new ViewData("/jsp/webframework/scheduler/schedulerOverview.jsp");
	}

	/**
	 * 打开Job列表页面
	 * 
	 * @return
	 */
	@RequestPath(path = "/showJobList")
	public ViewData showLogList() {
		return new ViewData("/jsp/webframework/scheduler/jobList.jsp");
	}

	/**
	 * 打开编辑任务页面
	 * 
	 * @param request
	 * @return
	 */
	@RequestPath(path = "/showEditJob")
	public ViewData showEditJob(HttpServletRequest request) {

		String jobName = request.getParameter("jobName");
		String jobGroup = request.getParameter("jobGroup");

		Map<String, Object> dataMap = new HashMap<>();

		dataMap.put("jobName", jobName);
		dataMap.put("jobGroup", jobGroup);

		return new ViewData("/jsp/webframework/scheduler/editJob.jsp", dataMap);
	}

	/**
	 * 获取定时任务服务
	 * 
	 * @return
	 */
	private IQuartzService getIQuartzService() {
		return WebContext.getInstance().getQuartzService();
	}

	/**
	 * 获取定时调度框架信息
	 * 
	 * @return
	 */
	@RequestPath(path = "/getQuartzData")
	@ResponseJSON
	public JsonResult getQuartzData() {

		JsonResult result = new JsonResult();
		result.setFlag(CommonConstant.FAIL);

		try {
			SchedulerInfo schedulerInfo = getIQuartzService().getSchedulerState();
			List<Map<String, Object>> contextMapList = this.getContextMapList();

			Map<String, Object> dataMap = new HashMap<>();

			dataMap.put("schedulerInfo", schedulerInfo);
			dataMap.put("contextMapList", contextMapList);

			result.setData(dataMap);

			result.setFlag(CommonConstant.SUCCESS);
		} catch (Exception e) {
			super.businessLogger.error(e.getMessage(), e);
		}

		return result;

	}

	/**
	 * 获取所有的job
	 * 
	 * @param request
	 * @return
	 */
	@RequestPath(path = "/getQuartzJobData")
	@ResponseJSON
	public Object getQuartzJobData(HttpServletRequest request) {
		Map<String, Object> resultMap = new HashMap<>();

		try {

			Map<String, Object> parameterMap = new HashMap<>();
			Page page = super.getPageBean(request);

			List<QrtzJobDetail> list = schedulerService.getAllJob(parameterMap, page, new ArrayList<OrderByBean>());
			int count = schedulerService.getJobCount(parameterMap);
			resultMap.put("tableData", list);
			resultMap.put("count", count);
		} catch (Exception e) {
			super.businessLogger.error(e.getMessage(), e);
		}

		return resultMap;
	}
	
	/**
	 * 保存任务
	 * 
	 * @param request
	 * @return
	 */
	@RequestPath(path = "/saveJobDetail")
	@ResponseJSON
	public JsonResult saveJobDetail(HttpServletRequest request){
		JsonResult result = new JsonResult();
		result.setFlag(CommonConstant.FAIL);
		try{
			String jsonData = request.getParameter("jsonData");
			JSONObject jsObject = JSON.parseObject(jsonData);

			String jobClass = super.getStringFromJSONObject("jobClass", jsObject, StringUtil.BLANK);
			String description = super.getStringFromJSONObject("description", jsObject, StringUtil.BLANK);
			String jobName = super.getStringFromJSONObject("jobName", jsObject, StringUtil.BLANK);
			String jobGroup = super.getStringFromJSONObject("jobGroup", jsObject, StringUtil.BLANK);
			
			JobDetail jobDetail = getIQuartzService().bulidAndSaveJob(jobName, jobGroup, jobClass, description, null);
			
			Map<String,Object> dataMap = new HashMap<>();
			
			dataMap.put("jobName", jobDetail.getKey().getName());
			dataMap.put("jobGroup", jobDetail.getKey().getName());
			result.setData(dataMap);
			
			result.setFlag(CommonConstant.SUCCESS);
		}catch(Exception e){
			super.businessLogger.error(e.getMessage(), e);
		}
		
		return result;
	}

	/**
	 * 查询任务对应的触发器
	 * 
	 * @param request
	 * @return
	 */
	@RequestPath(path = "/getJobTriggerList")
	@ResponseJSON
	public Object getJobTriggerList(HttpServletRequest request) {

		Map<String, Object> resultMap = new HashMap<>();

		try {

			String jobName = request.getParameter("jobName");
			String jobGroup = request.getParameter("jobGroup");

			List<Map<String, String>> dataList = new ArrayList<>();

			if (StringUtil.isNotNull(jobName) && StringUtil.isNotNull(jobGroup)) {
				List<Trigger> list = getIQuartzService().getTriggersFromJob(jobName, jobGroup);
				for (Trigger trigger : list) {

					Map<String, String> tiggerMap = getTriggerInfo(trigger);
					dataList.add(tiggerMap);

				}
			}

			resultMap.put("tableData", dataList);
			resultMap.put("count", dataList.size());
		} catch (Exception e) {
			super.businessLogger.error(e.getMessage(), e);
		}

		return resultMap;

	}

	/**
	 * 获取页面显示使用的触发器信息
	 * 
	 * @param trigger
	 * @return
	 * @throws SchedulerException
	 */
	private Map<String, String> getTriggerInfo(Trigger trigger) throws SchedulerException {

		Map<String, String> tiggerMap = new HashMap<>();

		trigger.getEndTime();

		tiggerMap.put("tiggerGroupName", trigger.getKey().getGroup());
		tiggerMap.put("tiggerName", trigger.getKey().getName());
		tiggerMap.put("description", trigger.getDescription());
		tiggerMap.put("previousFireTime", DateUtil.getFormatDateStr(DateUtil.YYYY_MM_DD_HH_MM_SS, trigger.getPreviousFireTime()));
		tiggerMap.put("nextFireTime", DateUtil.getFormatDateStr(DateUtil.YYYY_MM_DD_HH_MM_SS, trigger.getNextFireTime()));

		String type;

		if (trigger instanceof SimpleTrigger) {
			type = "间隔执行";
		} else if (trigger instanceof CronTrigger) {
			type = "周期执行";
		} else {
			type = trigger.getClass().getName();
		}

		tiggerMap.put("tiggerType", type);

		String triggerState = getIQuartzService().getTriggerState(trigger.getKey().getName(), trigger.getKey().getGroup());
		tiggerMap.put("triggerState", triggerState);

		return tiggerMap;

	}

	/**
	 * 获取当前调度器中正在执行任务信息
	 * 
	 * @return
	 * @throws SchedulerException
	 */
	private List<Map<String, Object>> getContextMapList() throws SchedulerException {

		List<Map<String, Object>> resultList = new ArrayList<>();

		List<JobExecutionContext> jobExecutionList = getIQuartzService().getScheduler().getCurrentlyExecutingJobs();
		for (JobExecutionContext context : jobExecutionList) {

			Map<String, Object> contextMap = new HashMap<>();

			contextMap.put("scheduledFireTime", DateUtil.getFormatDateStr(DateUtil.YYYY_MM_DD_HH_MM_SS, context.getScheduledFireTime()));
			contextMap.put("name", context.getJobDetail().getKey().getName());
			contextMap.put("groupName", context.getJobDetail().getKey().getGroup());
			contextMap.put("fireTime", DateUtil.getFormatDateStr(DateUtil.YYYY_MM_DD_HH_MM_SS, context.getFireTime()));
			contextMap.put("triggerName", context.getTrigger().getKey().getName());

			resultList.add(contextMap);
		}

		return resultList;
	}

	/**
	 * 启动调度器
	 * 
	 * @return
	 */
	@RequestPath(path = "/startScheduler")
	@ResponseJSON
	public JsonResult startScheduler() {
		JsonResult result = new JsonResult();
		result.setFlag(CommonConstant.FAIL);
		try {

			getIQuartzService().start();

			result.setFlag(CommonConstant.SUCCESS);
		} catch (Exception e) {
			result.setMsg(e.getMessage());
			super.businessLogger.error(e.getMessage(), e);
		}

		return result;

	}

	/**
	 * 停止调度器
	 * 
	 * @return
	 */
	@RequestPath(path = "/shutDownScheduler")
	@ResponseJSON
	public JsonResult shutDownScheduler() {
		JsonResult result = new JsonResult();
		result.setFlag(CommonConstant.FAIL);
		try {
			getIQuartzService().shutdown();
			result.setFlag(CommonConstant.SUCCESS);
		} catch (Exception e) {
			result.setMsg(e.getMessage());
			super.businessLogger.error(e.getMessage(), e);
		}

		return result;

	}

	/**
	 * 暂停所有任务
	 * 
	 * @return
	 */
	@RequestPath(path = "/pauseAllSchedulerTask")
	@ResponseJSON
	public JsonResult pauseAllSchedulerTask() {
		JsonResult result = new JsonResult();
		result.setFlag(CommonConstant.FAIL);
		try {
			getIQuartzService().pauseAll();
			result.setFlag(CommonConstant.SUCCESS);
		} catch (Exception e) {
			result.setMsg(e.getMessage());
			super.businessLogger.error(e.getMessage(), e);
		}

		return result;

	}

	/**
	 * 恢复所有任务
	 * 
	 * @return
	 */
	@RequestPath(path = "/resumeAllSchedulerTask")
	@ResponseJSON
	public JsonResult resumeAllSchedulerTask() {
		JsonResult result = new JsonResult();
		result.setFlag(CommonConstant.FAIL);
		try {
			getIQuartzService().resumeAll();
			result.setFlag(CommonConstant.SUCCESS);
		} catch (Exception e) {
			result.setMsg(e.getMessage());
			super.businessLogger.error(e.getMessage(), e);
		}

		return result;

	}
	
	/**
	 * 立即执行任务
	 * 
	 * @param request
	 * @return
	 */
	@RequestPath(path = "/excuteNow")
	@ResponseJSON
	public JsonResult excuteNow(HttpServletRequest request){
		JsonResult result = new JsonResult();
		result.setFlag(CommonConstant.FAIL);
		
		String jobName = request.getParameter("jobName");
		String jobGroup = request.getParameter("jobGroup");
		
		try {
			getIQuartzService().executeNow(jobName, jobGroup);
			result.setFlag(CommonConstant.SUCCESS);
		} catch (Exception e) {
			result.setMsg(e.getMessage());
			super.businessLogger.error(e.getMessage(), e);
		}
		
		return result;
	}

}
